package org.common.utils.database.mapper;

import cn.hutool.core.util.ClassUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Mapper管理器
 */
public class MapperManager {

    private static final Logger log = LoggerFactory.getLogger(MapperManager.class);

    /**
     * 数据源
     */
    private static DataSource DATA_SOURCE = null;

    /**
     * Mapper实现类列表<实现类类,Mapper实现类对象>
     */
    private static final ConcurrentHashMap<Class<?> , AbstractMapper<?>> MAPPER_MAP = new ConcurrentHashMap<>();

    /**
     * 扫描并初始化Mapper实现类
     */
    private static void initMapper() {
        //已经初始化过
        if(!MAPPER_MAP.isEmpty())
            return;

        Set<Class<?>> classSet = ClassUtil.scanPackageBySuper("", AbstractMapper.class);
        try {
            for (Class<?> clzss : classSet) {
                AbstractMapper<?> mapperObject = (AbstractMapper<?>)clzss.getConstructor().newInstance();
                MAPPER_MAP.put(clzss , mapperObject);
                log.info("MapperManager.initMapper scan Mapper : {}" , clzss.getName());
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 设置数据源
     * @param dataSource
     */
    public synchronized static void setDataSource(DataSource dataSource) {
        if(DATA_SOURCE != null) {
            throw new RuntimeException("dataSource already set");
        }

        initMapper();
        DATA_SOURCE = dataSource;
    }

    public static <T> T getMapper(Class<T > clzss) {
        return (T)MAPPER_MAP.get(clzss);
    }

    static Connection getConnection() throws SQLException {
        return DATA_SOURCE.getConnection();
    }
}
